package com.ccys.common.util;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Iterator;
import java.util.Map;
import java.util.Optional;

/**
 * 网络请求工具类
 */
@Slf4j
@Component
public class RestUtil {

    /**
     * 请求超时时间 单位ms
     */
    private static final int HTTP_TIME_OUT = 60000;

    private static RestTemplate restTemplate = null;

    static {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setConnectionRequestTimeout(HTTP_TIME_OUT);
        factory.setConnectTimeout(HTTP_TIME_OUT);
        factory.setReadTimeout(HTTP_TIME_OUT);
        RestUtil.restTemplate = new RestTemplate(factory);
    }

    /**
     * 使用restTemplate进行网络请求，判断链接是否可用
     *
     * @param url
     * @return
     */
    public static boolean isConnect(String url) {
        if (RestUtil.restTemplate == null) {
            log.warn("RestTemplate为空");
            return false;
        }
        try {
            HttpHeaders httpHeaders = new HttpHeaders();
            HttpEntity entity = new HttpEntity<>(httpHeaders);
            RestUtil.restTemplate.exchange(url, HttpMethod.HEAD, entity, String.class, Optional.ofNullable(null));
        } catch (Exception e) {
            if (e.getMessage().contains("Connection refused: connect")) {
                log.warn("网络请求超时!!!{}", e.getMessage());
                return false;
            }
        }
        return true;
    }

    /**
     * 使用restTemplate进行网络请求
     * <p>
     * Form表单
     *
     * @param url       请求路径
     * @param method    请求方法
     * @param headerMap 请求头
     * @param paramMap  请求参数
     * @return
     */
    public static String executeForm(String url, HttpMethod method, Map<String, String> headerMap, Map<String, String> paramMap) {
        if (RestUtil.restTemplate == null) {
            log.warn("RestTemplate为空");
            return "";
        }
        try {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            if (headerMap != null && headerMap.size() > 0) {
                Iterator<Map.Entry<String, String>> iterator = headerMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, String> entry = iterator.next();
                    httpHeaders.add(entry.getKey(), entry.getValue());
                }
            }
            HttpEntity entity = new HttpEntity<>(httpHeaders);
            if (paramMap != null && paramMap.size() > 0) {
                switch (method) {
                    case GET:
                        url = url + "?" + getString(paramMap);
                        break;
                    default:
                        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
                        Iterator<Map.Entry<String, String>> iterator = paramMap.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, String> entry = iterator.next();
                            body.add(entry.getKey(), entry.getValue());
                        }
                        entity = new HttpEntity<>(body, httpHeaders);
                        break;
                }
            }
            ResponseEntity<String> response = RestUtil.restTemplate.exchange(url, method, entity, String.class, Optional.ofNullable(null));
            return response.getBody();
        } catch (Exception e) {
            if (e.getMessage().contains("Connection refused: connect")) {
                log.warn("网络Form表单数据请求超时!!!{}", e.getMessage());
            } else {
                log.warn("网络Form表单数据请求异常!!!{}", e.getMessage());
            }
        }
        return "";
    }


    /**
     * 使用restTemplate进行网络请求
     * <p>
     * Json格式
     *
     * @param url       请求路径
     * @param method    请求方法 POST, PUT, DELETE
     * @param headerMap 请求头
     * @param paramMap  请求参数
     * @return
     */
    public static String executeJson(String url, HttpMethod method, Map<String, String> headerMap, Map<String, Object> paramMap) {
        if (RestUtil.restTemplate == null) {
            log.warn("RestTemplate为空");
            return "";
        }
        try {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Content-Type", "application/json;charset=utf-8");
            if (headerMap != null && headerMap.size() > 0) {
                Iterator<Map.Entry<String, String>> iterator = headerMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, String> entry = iterator.next();
                    httpHeaders.add(entry.getKey(), entry.getValue());
                }
            }
            HttpEntity entity = new HttpEntity<>(httpHeaders);
            if (paramMap != null && paramMap.size() > 0) {
                switch (method) {
                    case POST:
                    case PUT:
                    case DELETE:
                        String body = JSONObject.toJSONString(paramMap);
                        entity = new HttpEntity<>(body, httpHeaders);
                        break;
                    default:
                        log.warn("请求方法暂不支持");
                        return "";
                }
            }
            ResponseEntity<String> response = RestUtil.restTemplate.exchange(url, method, entity, String.class, Optional.ofNullable(null));
            return response.getBody();
        } catch (Exception e) {
            if (e.getMessage().contains("Connection refused: connect")) {
                log.warn("网络Json数据请求超时!!!{}", e.getMessage());
            } else {
                log.warn("网络Json数据请求异常!!!{}", e.getMessage());
            }
        }
        return "";
    }


    /**
     * Map kv拼接
     * key1=value1&key2=value2
     *
     * @param map
     * @return
     */
    @NotNull
    private static String getString(@NotNull Map<String, String> map) {
        StringBuffer sbf = new StringBuffer();
        Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            if (sbf.length() > 0) {
                sbf.append("&");
            }
            sbf.append(entry.getKey());
            sbf.append("=");
            sbf.append(entry.getValue());
        }
        return sbf.toString();
    }


}
